Schedule (effect)
繰り返しの処理を制御する仕組み
めちゃくちゃ宣言的に実行方法を指定できる
Schedule自体がcomposableになっている
mapやintersectionが用意されており、合成してScheduleを構築できる
docs
examples
前提として、Scheduleとは別に、下記のような繰り返し実行を行うAPI (Repetition (effect))がある
e.g.
Effect.retry
失敗したときに繰り返す
Effect.repeat
成功したときに繰り返す
etc.
これらについて、どういう条件で retry/repeat するかというポリシーをScheduleで表現する
例えば、taskというEffectがあった時に下記のように指定できる
code:ts
Effect.retry(task, Schedule.fixed("100 millis")) // 100msごとにretryされる
Effect.retry(task, Schedule.exponential("10 millis")) // exponential backooffされる
同じ「retry」ではあるが、どういう条件で retry するのかのポリシーを指定できるのがわかる
要するに、Strategyパターンになっている
無限・固定回数の繰り返し
Schedule.forever
Schedule.once
Schedule.recurs
実行間隔を制御する
Schedule.spaced
Schedule.fixed
遅延を徐々に増やす
Schedule.exponential
Schedule.fibonacci
自分で合成も可能
#wip
型
code:_
Schedule<Out, In, Requirements>
Out: スケジュールが「出力する値」の型
e.g.「何回目の実行か」などの情報を出せる
In: スケジュールが「入力として受け取る値」の型
e.g. retry の場合は「エラー」、repeat の場合は「処理結果」など
Requirements: スケジュールの実行に追加で必要なサービスやリソース
e.g. 時間計測のための Clock など
Scheduleは代数的に合成可能であるgpt-5.icon
基本的なSchedule同士を合成して、新たなScheduleを作れる
https://effect.website/docs/scheduling/schedule-combinators/
Schedule.union
両方のスケジュールが「まだ続けたい」と言っている限り続く。
短い方の delay を採用。
例: exponential(100ms) と spaced(1s) を union → 初期は指数的に速く、のちに1秒間隔に収束。
Schedule.intersect
両方のスケジュールが「続けたい」と言わないと終了。
長い方の delay を採用。
例: exponential(10ms) と recurs(5) → 5回まで指数的に実行して終了。
3. Sequencing (andThen)
Schedule.andThen
最初のスケジュールを全部終えてから、次のスケジュールに切り替える。
例: recurs(5) → 5回即実行 → その後 spaced(1s) に移行。
ランダム性を導入
Schedule.jittered
delay にランダム性を加える。
同期的な大量アクセスを避けるのに有効(スロットルの雪崩回避)。
例: jittered(exponential(10ms)) → 毎回少しズレる指数バックオフ。
制御するフィルタ
Schedule.whileInput
Schedule.whileOutput
入力や出力を見て「続けるかどうか」を決められる。
例: whileOutput(recurs(5), n => n <= 2) → 3回目以降は止まる。
遅延を動的に変更
Schedule.modifyDelay
実行回数や出力に応じて delay を変更。
例: spaced(1s) → 3回目以降は 100ms に短縮。
タップ (副作用注入)
Schedule.tapInput
Schedule.tapOutput
スケジュール自体は変えずに、ログなどの副作用を仕込める。
例: tapOutput(recurs(2), n => Console.log(...))
Schedule.compose
code:ts
// リトライ方針: 指数バックオフ + 最大3回(合計4トライ)
const retryPolicy = pipe(
Schedule.exponential(Duration.millis(200)),
Schedule.compose(Schedule.recurs(3)), // 追加で3回まで
);
Schedule.addDelay
https://effect.website/docs/scheduling/examples/